package com.xinting.piano.app;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SparseArray;

import com.xinting.piano.data.PApp;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by wuxinting on 15/11/13.
 * 日常任务的android service
 * 日常更新检查、系统通告、信件、动态等
 */
public class PRoutineService extends Service {

    public static final String LOG_TAG = PApp.LOG_TAG+"_routine";

    private static int NOTIFY_ID = 1;
    public static final int MSG_NOTIFY = 1;
    public static final int MSG_ADD_ROUTINE_TASK = 3;
    public static final int MSG_RM_ROUTINE_TASK = 4;

    private final int MAX_THREADS = 7;

    private NotificationManager mNM;
    private final Messenger mMessenger = new Messenger(new IncomingHandler());

    private ScheduledThreadPoolExecutor scheduler;
    //保存所有的日常任务
    private SparseArray<ScheduledFuture> routineTasks;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        scheduler = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(MAX_THREADS);

        routineTasks = new SparseArray<>();
    }

    /**
     * handler of incoming messages from clients
     */
    private class IncomingHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_NOTIFY:
                    Notification notification = (Notification) msg.obj;
                    mNM.notify(NOTIFY_ID++, notification);
                    Log.v(PApp.LOG_TAG, "receive notify request.");
                    break;
                case MSG_ADD_ROUTINE_TASK: {
                    IRoutineTask task = (IRoutineTask) msg.obj;
                    task.setMessenger(mMessenger);

                    ScheduledFuture scheduledFuture;
                    if (task.getPeriod() != -1) {
                        scheduledFuture = scheduler.scheduleAtFixedRate(task, task.getDelay(), task.getPeriod(), TimeUnit.MILLISECONDS);
                    } else {
                        scheduledFuture = scheduler.schedule(task, task.getDelay(), TimeUnit.MILLISECONDS);
                    }
                    if (scheduledFuture != null) {
                        routineTasks.append(task.getId(), scheduledFuture);
                    }
                }
                case MSG_RM_ROUTINE_TASK: {
                    //remove routine task, arg1 refer the id
                    ScheduledFuture task = routineTasks.get(msg.arg1, null);
                    if (task != null) {
                        Log.i(LOG_TAG, "remove task " + msg.arg1);
                        if (!task.cancel(true)) {
                            Log.e(LOG_TAG, "Remove task " + msg.arg1 + " failed.");
                        }
                    }
                }
                    break;
            }
        }
    }

    /**
     * 日常任务的接口
     */
    public interface IRoutineTask extends Runnable {

        /**
         * 该task的id
         * @return
         */
        int getId();

        /**
         * 运行延时,ms
         * @return
         */
        long getDelay();

        /**
         * 运行间隔，ms
         * 如果为-1,将只运行一次
         * @return
         */
        long getPeriod();

        /**
         * set service's messenger
         * @param messenger
         */
        void setMessenger(Messenger messenger);

    }

}
